Pythonパッケージの依存関係とライセンスを確認する
はじめに
データアナリティクス事業本部のkobayashiです。
Pythonを使って開発を行っていると、AWSのリソースを扱う際にはboto3
でしたりデータ解析を行う場合はPnadas,Scipy
など様々なパッケージを使っているかと思います。
今回、その利用しているパッケージの依存関係やパッケージを調べる機会があったのでその方法をまとめたいと思います。
環境
- Python 3.7.4
- pipdeptree 1.0.0
- pip-licenses 2.2.1
パッケージ依存関係とライセンスを調べるツール
今回使用したツールは以下になります。どちらのツールもきちんと継続的にメンテナンスされており、pip
でインストールできるのでこれらを使いました。
- パッケージ依存関係をツリーで表示するツール
- pipdeptree · PyPI
pip
でインストールしたPythonパッケージを依存関係ツリー形式で表示するCLIツール
- pipdeptree · PyPI
- パッケージのライセンス上表を表示するツール
- pip-licenses · PyPI
pip
でインストールしたPythonパッケージのソフトウェアライセンスを確認するCLIツール
- pip-licenses · PyPI
pipdeptreeとpip-licensesを使いパッケージを調べる
pipdeptreeとpip-licensesもpip list
で表示されるパッケージが対象になるので、マシンにインストールされたPythonパッケージを調べる際は特に環境を作るなどは必要なくpipでこれらのツールをインストールして使えばよいのですが、これらのツールを使う場面としてはプロジェクト単位で利用するPythonパッケージの依存関係やライセンス情報を使う場面だと思います。
今回はこのように特定のPythonパッケージだけを対象にした場合を想定して進めます。
準備
まずはじめにPythonの仮想環境を作成します。簡単にPython3.3で追加されたvenv
で構築します。
# ディレクトリを作成 $ mkdir {プロジェクト名} $ cd {プロジェクト名} # venvの名前で仮想環境を作成 $ python3 -m venv venv # 仮想環境を有効化 $ source venv/bin/activate
パッケージをインストール
調査したいパッケージをrequirements.txt
にまとめてインストールします。
今回は以下のパッケージを調べてみたいと思います。
$ cat requirements.txt pipdeptree pip-licenses boto3 pandas pyodbc scipy matplotlib scikit-learn scrapy MoviePy bottle
pipdeptreeとpip-licensesもpip
でインストールする必要があるのでrequirements.txt
のリストに含めて一緒にインストールしてしまいます。
# 仮想環境のPythonバージョン確認 (venv) kobayashi@localhost% python -V Python 3.7.4 # パッケージリストを表示 (venv) kobayashi@localhost% pip list Package Version ---------- ------- pip 19.0.3 setuptools 40.8.0 # requirements.txtファイルからパッケージのインストール (venv) kobayashi@localhost% pip install -r requirements.txt Collecting pip-licenses (from -r requirements.txt (line 1)) Using cached https://files.pythonhosted.org/packages/2e/8a/b8eb114545d9e984fcc013ef544c487aa2c02489a66185a82108625784a5/pip_licenses-2.2.1-py3-none-any.whl Collecting pipdeptree (from -r requirements.txt (line 2)) Using cached https://files.pythonhosted.org/packages/5c/3f/4a3e02c283fb7d3084456cbca8d22b790b9e176b4c0075bc38e5abe166c6/pipdeptree-1.0.0-py3-none-any.whl Collecting boto3 (from -r requirements.txt (line 3)) Downloading https://files.pythonhosted.org/packages/94/8b/42119ee46d95952d082876d4d00f74f381f0a9d987de18781a15ba34057d/boto3-1.14.28-py2.py3-none-any.whl (128kB) 100% |████████████████████████████████| 133kB 3.1MB/s Collecting pandas (from -r requirements.txt (line 4)) Using cached https://files.pythonhosted.org/packages/5d/24/91ad2da4a1da2747595d2f47f858a131036f598fb495ec6346d08d8b8df6/pandas-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl Collecting pyodbc (from -r requirements.txt (line 5)) Downloading https://files.pythonhosted.org/packages/4a/a3/3de345058cccc78f43a11f9b08ac9b756542cf3d36457704f2432b2f344d/pyodbc-4.0.30-cp37-cp37m-macosx_10_9_x86_64.whl (63kB) 100% |████████████████████████████████| 71kB 7.3MB/s ... # パッケージリストを表示 (venv) kobayashi@localhost% pip list Package Version ---------------- --------- attrs 19.3.0 Automat 20.2.0 boto3 1.14.33 botocore 1.17.33 bottle 0.12.18 certifi 2020.6.20 cffi 1.14.1 chardet 3.0.4 constantly 15.1.0 cryptography 3.0 cssselect 1.1.0 cycler 0.10.0 decorator 4.4.2 docutils 0.15.2 hyperlink 19.0.0 idna 2.10 imageio 2.9.0 imageio-ffmpeg 0.4.2 incremental 17.5.0 itemadapter 0.1.0 jmespath 0.10.0 joblib 0.16.0 kiwisolver 1.2.0 lxml 4.5.2 matplotlib 3.3.0 moviepy 1.0.3 numpy 1.19.1 pandas 1.1.0 parsel 1.6.0 Pillow 7.2.0 pip 19.0.3 pip-licenses 2.3.0 pipdeptree 1.0.0 proglog 0.1.9 Protego 0.1.16 PTable 0.9.2 pyasn1 0.4.8 pyasn1-modules 0.2.8 pycparser 2.20 PyDispatcher 2.0.5 PyHamcrest 2.0.2 pyodbc 4.0.30 pyOpenSSL 19.1.0 pyparsing 2.4.7 python-dateutil 2.8.1 pytz 2020.1 queuelib 1.5.0 requests 2.24.0 s3transfer 0.3.3 scikit-learn 0.23.1 scipy 1.5.2 Scrapy 2.2.1 service-identity 18.1.0 setuptools 40.8.0 six 1.15.0 threadpoolctl 2.1.0 tqdm 4.48.0 Twisted 20.3.0 urllib3 1.25.10 w3lib 1.22.0 zope.interface 5.1.0
以上で準備が終わったので実際にCLIで依存関係とライセンスを確認してみます。
pipdeptreeで依存関係を確認
Python仮想環境を有効化した上でpipdeptree
コマンドを実行します。
pip freeze
と違い最上位のパッケージに対して依存しているパッケージがツリー形式で表示され依存関係が非常にわかりやすくなっています。
(venv) kobayashi@localhost% pipdeptree boto3==1.14.33 - botocore [required: >=1.17.33,<1.18.0, installed: 1.17.33] - docutils [required: >=0.10,<0.16, installed: 0.15.2] - jmespath [required: >=0.7.1,<1.0.0, installed: 0.10.0] - python-dateutil [required: >=2.1,<3.0.0, installed: 2.8.1] - six [required: >=1.5, installed: 1.15.0] - urllib3 [required: >=1.20,<1.26, installed: 1.25.10] - jmespath [required: >=0.7.1,<1.0.0, installed: 0.10.0] - s3transfer [required: >=0.3.0,<0.4.0, installed: 0.3.3] - botocore [required: >=1.12.36,<2.0a.0, installed: 1.17.33] - docutils [required: >=0.10,<0.16, installed: 0.15.2] - jmespath [required: >=0.7.1,<1.0.0, installed: 0.10.0] - python-dateutil [required: >=2.1,<3.0.0, installed: 2.8.1] - six [required: >=1.5, installed: 1.15.0] - urllib3 [required: >=1.20,<1.26, installed: 1.25.10] bottle==0.12.18 matplotlib==3.3.0 - cycler [required: >=0.10, installed: 0.10.0] - six [required: Any, installed: 1.15.0] - kiwisolver [required: >=1.0.1, installed: 1.2.0] - numpy [required: >=1.15, installed: 1.19.1] - pillow [required: >=6.2.0, installed: 7.2.0] - pyparsing [required: >=2.0.3,!=2.1.6,!=2.1.2,!=2.0.4, installed: 2.4.7] - python-dateutil [required: >=2.1, installed: 2.8.1] - six [required: >=1.5, installed: 1.15.0] moviepy==1.0.3 - decorator [required: >=4.0.2,<5.0, installed: 4.4.2] - imageio [required: >=2.5,<3.0, installed: 2.9.0] - numpy [required: Any, installed: 1.19.1] - pillow [required: Any, installed: 7.2.0] - imageio-ffmpeg [required: >=0.2.0, installed: 0.4.2] - numpy [required: >=1.17.3, installed: 1.19.1] - numpy [required: Any, installed: 1.19.1] - proglog [required: <=1.0.0, installed: 0.1.9] - tqdm [required: Any, installed: 4.48.0] - requests [required: >=2.8.1,<3.0, installed: 2.24.0] - certifi [required: >=2017.4.17, installed: 2020.6.20] - chardet [required: >=3.0.2,<4, installed: 3.0.4] - idna [required: >=2.5,<3, installed: 2.10] - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.10] - tqdm [required: >=4.11.2,<5.0, installed: 4.48.0] pandas==1.1.0 - numpy [required: >=1.15.4, installed: 1.19.1] - python-dateutil [required: >=2.7.3, installed: 2.8.1] - six [required: >=1.5, installed: 1.15.0] - pytz [required: >=2017.2, installed: 2020.1] pip-licenses==2.3.0 - PTable [required: Any, installed: 0.9.2] pipdeptree==1.0.0 - pip [required: >=6.0.0, installed: 19.0.3] pyodbc==4.0.30 scikit-learn==0.23.1 - joblib [required: >=0.11, installed: 0.16.0] - numpy [required: >=1.13.3, installed: 1.19.1] - scipy [required: >=0.19.1, installed: 1.5.2] - numpy [required: >=1.14.5, installed: 1.19.1] - threadpoolctl [required: >=2.0.0, installed: 2.1.0] Scrapy==2.2.1 - cryptography [required: >=2.0, installed: 3.0] - cffi [required: >=1.8,!=1.11.3, installed: 1.14.1] - pycparser [required: Any, installed: 2.20] - six [required: >=1.4.1, installed: 1.15.0] - cssselect [required: >=0.9.1, installed: 1.1.0] - itemadapter [required: >=0.1.0, installed: 0.1.0] - lxml [required: >=3.5.0, installed: 4.5.2] - parsel [required: >=1.5.0, installed: 1.6.0] - cssselect [required: >=0.9, installed: 1.1.0] - lxml [required: Any, installed: 4.5.2] - six [required: >=1.6.0, installed: 1.15.0] - w3lib [required: >=1.19.0, installed: 1.22.0] - six [required: >=1.4.1, installed: 1.15.0] - protego [required: >=0.1.15, installed: 0.1.16] - six [required: Any, installed: 1.15.0] - PyDispatcher [required: >=2.0.5, installed: 2.0.5] - pyOpenSSL [required: >=16.2.0, installed: 19.1.0] - cryptography [required: >=2.8, installed: 3.0] - cffi [required: >=1.8,!=1.11.3, installed: 1.14.1] - pycparser [required: Any, installed: 2.20] - six [required: >=1.4.1, installed: 1.15.0] - six [required: >=1.5.2, installed: 1.15.0] - queuelib [required: >=1.4.2, installed: 1.5.0] - service-identity [required: >=16.0.0, installed: 18.1.0] - attrs [required: >=16.0.0, installed: 19.3.0] - cryptography [required: Any, installed: 3.0] - cffi [required: >=1.8,!=1.11.3, installed: 1.14.1] - pycparser [required: Any, installed: 2.20] - six [required: >=1.4.1, installed: 1.15.0] - pyasn1 [required: Any, installed: 0.4.8] - pyasn1-modules [required: Any, installed: 0.2.8] - pyasn1 [required: >=0.4.6,<0.5.0, installed: 0.4.8] - Twisted [required: >=17.9.0, installed: 20.3.0] - attrs [required: >=19.2.0, installed: 19.3.0] - Automat [required: >=0.3.0, installed: 20.2.0] - attrs [required: >=19.2.0, installed: 19.3.0] - six [required: Any, installed: 1.15.0] - constantly [required: >=15.1, installed: 15.1.0] - hyperlink [required: >=17.1.1, installed: 19.0.0] - idna [required: >=2.5, installed: 2.10] - incremental [required: >=16.10.1, installed: 17.5.0] - PyHamcrest [required: >=1.9.0,!=1.10.0, installed: 2.0.2] - zope.interface [required: >=4.4.2, installed: 5.1.0] - setuptools [required: Any, installed: 40.8.0] - w3lib [required: >=1.17.0, installed: 1.22.0] - six [required: >=1.4.1, installed: 1.15.0] - zope.interface [required: >=4.1.3, installed: 5.1.0] - setuptools [required: Any, installed: 40.8.0]
他にpipdeptree
コマンドの使い方として、-r
オプションを使って依存されているパッケージから依存しているパッケージを表示することもできます。
(venv) kobayashi@localhost% pipdeptree -r --p botocore,six botocore==1.17.29 - boto3==1.14.29 [requires: botocore>=1.17.29,<1.18.0] - s3transfer==0.3.3 [requires: botocore>=1.12.36,<2.0a.0] - boto3==1.14.29 [requires: s3transfer>=0.3.0,<0.4.0] six==1.15.0 - Automat==20.2.0 [requires: six] - Twisted==20.3.0 [requires: Automat>=0.3.0] - Scrapy==2.2.1 [requires: Twisted>=17.9.0] - cryptography==3.0 [requires: six>=1.4.1] ...
他オプションはpipdeptree -h
で確認するか、公式サイト(GitHub - naiquevin/pipdeptree: A command line utility to display dependency tree of the installed Python packages)をご確認ください。
pip-licensesでライセンス情報を確認
こちらもPython仮想環境を有効化した上でpip-licenses
コマンドを実行します。
(venv) kobayashi@localhost% pip-licenses Name Version License Automat 20.2.0 MIT Pillow 7.2.0 HPND Protego 0.1.16 BSD PyDispatcher 2.0.5 BSD PyHamcrest 2.0.2 New BSD Scrapy 2.2.1 BSD Twisted 20.3.0 MIT attrs 19.3.0 MIT boto3 1.14.33 Apache License 2.0 botocore 1.17.33 Apache License 2.0 bottle 0.12.18 MIT certifi 2020.6.20 MPL-2.0 cffi 1.14.1 MIT chardet 3.0.4 LGPL constantly 15.1.0 MIT cryptography 3.0 BSD or Apache License, Version 2.0 cssselect 1.1.0 BSD cycler 0.10.0 BSD decorator 4.4.2 new BSD License docutils 0.15.2 public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt) hyperlink 19.0.0 MIT idna 2.10 BSD-like imageio 2.9.0 BSD-2-Clause imageio-ffmpeg 0.4.2 BSD-2-Clause incremental 17.5.0 MIT itemadapter 0.1.0 BSD jmespath 0.10.0 MIT joblib 0.16.0 BSD kiwisolver 1.2.0 BSD lxml 4.5.2 BSD matplotlib 3.3.0 PSF moviepy 1.0.3 MIT License numpy 1.19.1 BSD pandas 1.1.0 BSD parsel 1.6.0 BSD pipdeptree 1.0.0 MIT License proglog 0.1.9 MIT - copyright Edinburgh Genome Foundry pyOpenSSL 19.1.0 Apache License, Version 2.0 pyasn1 0.4.8 BSD pyasn1-modules 0.2.8 BSD-2-Clause pycparser 2.20 BSD pyodbc 4.0.30 MIT pyparsing 2.4.7 MIT License python-dateutil 2.8.1 Dual License pytz 2020.1 MIT queuelib 1.5.0 BSD requests 2.24.0 Apache 2.0 s3transfer 0.3.3 Apache License 2.0 scikit-learn 0.23.1 new BSD scipy 1.5.2 BSD service-identity 18.1.0 MIT six 1.15.0 MIT threadpoolctl 2.1.0 UNKNOWN tqdm 4.48.0 MPLv2.0, MIT Licences urllib3 1.25.10 MIT w3lib 1.22.0 BSD zope.interface 5.1.0 ZPL 2.1
pip-licenses
コマンドにもいろいろなオプションがあります。これらを使って必要な情報を必要な形式で出力できますのでいくつかオプションの使用例を記載します。
- 公式サイトと詳細説明も表示する
(venv) kobayashi@localhost% pip-licenses --with-urls --with-description Name Version License URL Description PyYAML 5.1.2 MIT https://github.com/yaml/pyyaml YAML parser and emitter for Python awscli 1.16.286 Apache License 2.0 http://aws.amazon.com/cli/ Universal Command Line Environment for AWS. boto3 1.9.235 Apache License 2.0 https://github.com/boto/boto3 The AWS SDK for Python botocore 1.13.22 Apache License 2.0 https://github.com/boto/botocore Low-level, data-driven core of boto 3. ...
-
公式サイトと詳細説明の情報を付加し、csv形式でpython-licenses.csvファイルに出力する
(venv) kobayashi@localhost% pip-licenses --with-urls --format=csv --with-description --output-file=python-licenses.csv
他オプションはpip-licenses -h
で確認するか、公式サイト(GitHub - raimon49/pip-licenses: Dump the license list of packages installed with pip.)をご確認ください。
一応最後にPython仮想環境を抜ける処理を記述しておきます。
(venv) kobayashi@localhost% deactivate
まとめ
pipdeptreeとpip-licensesを使ってPythonパッケージの依存関係とライセンス情報を取得してみました。頻繁に使う場面はありませんが、プロジェクトが立ち上がった際など要所要所では必要になってくると思います。
最後まで読んで頂いてありがとうございました。